#include "widget.h"
#include "ui_widget.h"
#include <QTimer>
#include <QMessageBox>
#include <QThread>
#include <QSignalTransition>
#include <QSettings>
#include <QJsonObject>
#include <QJsonParseError>
#include <QJsonDocument>
#include "messageboxutil.h"
#include "Delay.h"


#define DEBUG 1

bool Widget::device_switch_flag = false;

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    QTimer::singleShot(0, this, &Widget::showLoginDialog);

    do_initSerialPort();
    InitEntIPPort();
    initGroupData();

    iniTextColor(StatusColor::Normal);

    // 连接plc状态信号
    connect(&plc_port, &ModbusSerialTest::newStatusBit, this, &Widget::do_updatelatestStatusCode);

    connect(&plc_port, &ModbusSerialTest::topPhotoRequest, [=](uint16_t state){
        m_plc_topPhotoRequest = state;
    });

    connect(&plc_port, &ModbusSerialTest::ABCD_PhotoRequest, [=](uint16_t state){
        m_plc_ABCD_PhotoRequest = state;
    });

    connect(&plc_port, &ModbusSerialTest::bottomPhotoRequest, [=](uint16_t state){
        m_plc_bottomPhotoRequest = state;
    });


    connect(&plc_port, &ModbusSerialTest::sensorStateMap, [=](QMap<QString, uint8_t> map){

        QString feedSensorStatusText = map.value("输入口检测信号") ? "上料" : "正常";
        QString liftSensorStatusText = map.value("顶升气缸正限位") ? "顶升" : "正常";
        QString chainWidthText = map.value("调宽气缸负限位") ? "窄" : "宽";
        QString rotateSensorStatusText = map.value("旋转轴原点") ? "已回原点" : "未回原点";
        QString cuttingSensorStatusText = map.value("输出口检测信号") ? "下料" : "正常";
        QString resetSensorStatusText = map.value("复位") ? "已复位" : "复位中";

        ui->LineEdit_feedSensorStatus->setText(feedSensorStatusText);
        ui->LineEdit_liftSensorStatus->setText(liftSensorStatusText);
        ui->lineEdit_chainWidth->setText(chainWidthText);
        ui->LineEdit_rotateSensorStatus->setText(rotateSensorStatusText);
        ui->LineEdit_cuttingSensorStatus->setText(cuttingSensorStatusText);
//        ui->lineEdit->setText(resetSensorStatusText);

        emit plcChainWidthCurrentSize(chainWidthText);
    });


    // 调用函数并获取状态步骤
    currentSteps = readStepsFromFile("./txt/steps.txt");


    // 初始状态机
    MyStateMachineInit();


    // 默认停止
    ui->btn_Stop->setEnabled(false);

}

Widget::~Widget()
{
    deleteStateMachine();// 释放状态机资源

    if(m_iniManager)
        delete m_iniManager;
    delete ui;
}

void Widget::showLoginDialog() {
    // 创建登录对话框
    Dialog_login login(this);
    // 显示登录对话框
    if(login.exec()!=QDialog::Accepted)
    {
        this->close();
    }
}

// 获取步骤文件
QStringList Widget::readStepsFromFile(const QString &fileName) {
    QStringList steps;
    QFile file(fileName);

    if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
        qWarning() << "无法打开文件";
        return steps;
    }

    QTextStream in(&file);
    while (!in.atEnd()) {
        QString line = in.readLine();
        steps.append(line);
    }

    file.close();
    return steps;
}

void Widget::InitEntIPPort()
{
    QSettings settings("./config/systemConfig.ini", QSettings::IniFormat);

    settings.beginGroup("system");

    QString netIP = settings.value("netIP").toString();

    QString netPort = settings.value("netPort").toString();

    settings.endGroup();

    // 初始化IP端口
    m_http = new HttpRequest(this, netIP + ":" + netPort);


    connect(m_http, &HttpRequest::urlChecked, [=](const QString &url, bool isValid){
        if(isValid)
        {
            setTextColor(ui->LineEdit_netWorkStatus, "已连接", StatusColor::Normal);
        } else {
            setTextColor(ui->LineEdit_netWorkStatus, "异常", StatusColor::Error);
        }
    });

}

void Widget::do_setCurrentGroupSize(QString groupSize)
{
    ui->LineEdit_workGroupSize->setText(groupSize);
}

void Widget::do_setCurrentGroupName(QString groupName)
{
    ui->LineEdit_currentWorkGroup->setText(groupName);
}

void Widget::iniTextColor(StatusColor status)
{
    do_setAllSensorShowTextColor("无", status);// 所有传感器状态初始化为 无 黑色

    setTextColor(ui->LineEdit_systemVersion, m_systemVersion, status);// 初始化系统版本显示

    setTextColor(ui->LineEdit_configFileName, m_configFileName, status); // 初始化系统配置文件名称

    setTextColor(ui->LineEdit_netWorkStatus, "未连接", status); // 初始化工控网连接显示

    setTextColor(ui->lineEdit_sideFillLightState, "未连接", status); // 初始化侧面补光连接显示

    setTextColor(ui->LineEdit_currentWorkGroup, "", status); // 初始化当前工作组显示
    setTextColor(ui->LineEdit_workGroupSize, "", status); // 初始化产品尺寸显示
    setTextColor(ui->LineEdit_currentStep, "", status); // 初始化PLC当前步骤显示
    setTextColor(ui->LineEdit_latestStatusCode, "", status); // 初始化PLC状态码显示
}


void Widget::do_setAllSensorShowTextColor(const QString &text, StatusColor status)
{
    setTextColor(ui->LineEdit_feedSensorStatus, text, status);// 上料

    setTextColor(ui->LineEdit_liftSensorStatus, text, status);// 顶升

    setTextColor(ui->LineEdit_rotateSensorStatus, text, status);// 旋转轴原点

    setTextColor(ui->LineEdit_cuttingSensorStatus, text, status);// 下料

    setTextColor(ui->lineEdit_chainWidth, text, status);// 调宽
}

void Widget::do_initTopFocus()
{
    const int angle = 1480;
    sendTopFormSetData(angle);
    Dialog_camAdjust::topCamadjustValue = angle;
}

void Widget::do_initSideFocus()
{
    const int angle = 1480;
    sendSideFormSetData(angle);
    Dialog_camAdjust::sideCamadjustValue = angle;
}

void Widget::setTopCamFocusLight(const int focus, const uint8_t light)
{
    qDebug() << "进入了 setTopCamFocusLight 函数.";
    qDebug() << "Focus: " << focus;
    if(focus != 0)
    {
        // 计算
        int adjustFocus = Dialog_camAdjust::calculateFocusRotation(Dialog_camAdjust::topCamadjustValue, focus);
        sendTopFormSetData(adjustFocus);// 发送
        qDebug() << "(Target value:" << focus << ") - (current value:" << Dialog_camAdjust::topCamadjustValue << ") = adjustFocus:" << adjustFocus;
        // 同步更新当前焦距
        Dialog_camAdjust::topCamadjustValue = focus;
    }

    // 设置顶部相机光源
    QString channelA = Dialog_LightControl::getSetLightsDataString("A", light);
    QString channelB = Dialog_LightControl::getSetLightsDataString("B", light);
    QString sData = channelA + channelB;
    sendTopRoSideLightAdjustData(sData);
}


void Widget::setSideCamFocusLight(const int focus, const uint8_t light, const uint8_t fill)
{
    qDebug() << "Focus: " << focus;
    if(focus != 0)
    {
        // 计算
        int adjustFocus = Dialog_camAdjust::calculateFocusRotation(Dialog_camAdjust::sideCamadjustValue, focus);
        sendSideFormSetData(adjustFocus);// 发送
        qDebug() << "(Target value:" << focus << ") - (current value:" << Dialog_camAdjust::sideCamadjustValue << ") = adjustFocus:" << adjustFocus;
        // 同步更新当前焦距
        Dialog_camAdjust::sideCamadjustValue = focus;
    }

    // 设置侧面相机光源
    QString channelC = Dialog_LightControl::getSetLightsDataString("C", light);
    QString channelD = Dialog_LightControl::getSetLightsDataString("D", light);
    QString sData = channelC + channelD;
    sendTopRoSideLightAdjustData(sData);

    // 设置侧面补光
    QString fillsData = Dialog_LightControl::getSetLightsDataString("B", fill);
    sendBottomLightAdjustData(fillsData);
}

void Widget::setBottomCamLight(const uint8_t light)
{
    // 设置底部光源
    QString fillsData = Dialog_LightControl::getSetLightsDataString("A", light);
    sendBottomLightAdjustData(fillsData);
}


// 工作组同步更新到plc
void Widget::updatePlcGroupData(const QString &groupName)
{
    qDebug() << "plc更新配方: " << groupName;

    int16_t currGroupNum = groupName.toInt();

    // 选择工作组

    // 写配方编号寄存器
    plc_port.do_setSendModbusRequest(6, 0xA466, (currGroupNum) * 400);

    // 读配方编号寄存器
//    plc_port.do_setSendModbusRequest(3, 0xA466, 1);

    // 复位
    plc_port.do_setSendModbusRequest(5, 1102, 0x00);   // 先拉低，确保能产生上升沿
    plc_port.do_setSendModbusRequest(5, 1102, 0xFF00); // 拉高，上升沿
    plc_port.do_setSendModbusRequest(5, 1102, 0xFF00);
    plc_port.do_setSendModbusRequest(5, 1102, 0x00);   // 拉低，下降沿
    plc_port.do_setSendModbusRequest(5, 1102, 0x00);
}

void Widget::GetCurrentGroupData()
{
    // 获取所有的组
    QStringList groups = m_iniManager->allGroups();
    QString currentGroup = "current";

    if (groups.isEmpty()) {
        qDebug() << "No groups found in the INI file.";
    } else {
        currentGroup = m_iniManager->readValue(currentGroup, "group").toString();
        qDebug() << "Current group:" << currentGroup;

        // 显示当前组的所有键值对
        QMap<QString, QString> map_group;

        QStringList keys = m_iniManager->allKeys(currentGroup);

        for(const QString &key : keys)
        {
            map_group.insert(key, m_iniManager->readValue(currentGroup, key).toString());
        }
        map_group.insert("currentGroup", m_iniManager->readValue("current", "group").toString());

        map_currentGroup = map_group;

        qDebug() << "map_group: " << map_group;

        ui->LineEdit_currentWorkGroup->setText(map_currentGroup.value("name"));
        ui->LineEdit_workGroupSize->setText(map_currentGroup.value("size"));
    }
}


void Widget::initGroupData()
{
    m_iniManager = new iniManager("./config/workGroupConfig.ini");

    GetCurrentGroupData();
}


void Widget::do_btn_configWorkGroup_clicked(const QString &productClass)
{
    Dialog_configWorkGroupParas *dialog = new Dialog_configWorkGroupParas(this);

    connect(this, &Widget::sendProductClassNewGroup, dialog, &Dialog_configWorkGroupParas::do_getProductClassNewGroup);

    connect(dialog, &Dialog_configWorkGroupParas::sendTopRoSideLightData, this, &Widget::sendTopRoSideLightAdjustData);
    connect(dialog,&Dialog_configWorkGroupParas::sendBottomLightData,this, &Widget::sendBottomLightAdjustData);
    connect(&top_side_light_sport,&SerialPortHandler::newQStringDataReceived,dialog,&Dialog_configWorkGroupParas::getTopLightRecv);
    connect(&bottom_light_sport,&SerialPortHandler::newQStringDataReceived,dialog,&Dialog_configWorkGroupParas::getBottomLightRecv);

    connect(dialog,&Dialog_configWorkGroupParas::sendTopAdjustData,this, &Widget::getTopAdjustData);
    connect(dialog,&Dialog_configWorkGroupParas::sendSideAdjustData,this, &Widget::getSideAdjustData);
    connect(&top_cam_focus_sport,&SerialPortHandler::newQByteArrayDataReceived,dialog, &Dialog_configWorkGroupParas::getTopAdjustRecv);
    connect(&side_cam_focus_sport,&SerialPortHandler::newQByteArrayDataReceived,dialog, &Dialog_configWorkGroupParas::getSideAdjustRecv);

    if(!productClass.isEmpty())
        sendProductClassNewGroup(productClass);

    dialog->exec();


    disconnect(dialog, &Dialog_configWorkGroupParas::sendTopRoSideLightData, this, &Widget::sendTopRoSideLightAdjustData);
    disconnect(dialog,&Dialog_configWorkGroupParas::sendBottomLightData,this, &Widget::sendBottomLightAdjustData);
    disconnect(&top_side_light_sport,&SerialPortHandler::newQStringDataReceived,dialog,&Dialog_configWorkGroupParas::getTopLightRecv);
    disconnect(&bottom_light_sport,&SerialPortHandler::newQStringDataReceived,dialog,&Dialog_configWorkGroupParas::getBottomLightRecv);


    disconnect(dialog,&Dialog_configWorkGroupParas::sendTopAdjustData,this, &Widget::getTopAdjustData);
    disconnect(dialog,&Dialog_configWorkGroupParas::sendSideAdjustData,this, &Widget::getSideAdjustData);
    disconnect(&top_cam_focus_sport,&SerialPortHandler::newQByteArrayDataReceived,dialog, &Dialog_configWorkGroupParas::getTopAdjustRecv);
    disconnect(&side_cam_focus_sport,&SerialPortHandler::newQByteArrayDataReceived,dialog, &Dialog_configWorkGroupParas::getSideAdjustRecv);

    disconnect(this, &Widget::sendProductClassNewGroup, dialog, &Dialog_configWorkGroupParas::do_getProductClassNewGroup);

    if(dialog != nullptr)
    {
        delete dialog;
    }
}


void Widget::on_btn_configWorkGroup_clicked()
{
    Dialog_configWorkGroupParas *dialog = new Dialog_configWorkGroupParas(this);

    connect(dialog, &Dialog_configWorkGroupParas::sendTopRoSideLightData, this, &Widget::sendTopRoSideLightAdjustData);
    connect(dialog,&Dialog_configWorkGroupParas::sendBottomLightData,this, &Widget::sendBottomLightAdjustData);
    connect(&top_side_light_sport,&SerialPortHandler::newQStringDataReceived,dialog,&Dialog_configWorkGroupParas::getTopLightRecv);
    connect(&bottom_light_sport,&SerialPortHandler::newQStringDataReceived,dialog,&Dialog_configWorkGroupParas::getBottomLightRecv);

    connect(dialog,&Dialog_configWorkGroupParas::sendTopAdjustData,this, &Widget::getTopAdjustData);
    connect(dialog,&Dialog_configWorkGroupParas::sendSideAdjustData,this, &Widget::getSideAdjustData);
    connect(&top_cam_focus_sport,&SerialPortHandler::newQByteArrayDataReceived,dialog, &Dialog_configWorkGroupParas::getTopAdjustRecv);
    connect(&side_cam_focus_sport,&SerialPortHandler::newQByteArrayDataReceived,dialog, &Dialog_configWorkGroupParas::getSideAdjustRecv);



    dialog->exec();


    disconnect(dialog, &Dialog_configWorkGroupParas::sendTopRoSideLightData, this, &Widget::sendTopRoSideLightAdjustData);
    disconnect(dialog,&Dialog_configWorkGroupParas::sendBottomLightData,this, &Widget::sendBottomLightAdjustData);
    disconnect(&top_side_light_sport,&SerialPortHandler::newQStringDataReceived,dialog,&Dialog_configWorkGroupParas::getTopLightRecv);
    disconnect(&bottom_light_sport,&SerialPortHandler::newQStringDataReceived,dialog,&Dialog_configWorkGroupParas::getBottomLightRecv);


    disconnect(dialog,&Dialog_configWorkGroupParas::sendTopAdjustData,this, &Widget::getTopAdjustData);
    disconnect(dialog,&Dialog_configWorkGroupParas::sendSideAdjustData,this, &Widget::getSideAdjustData);
    disconnect(&top_cam_focus_sport,&SerialPortHandler::newQByteArrayDataReceived,dialog, &Dialog_configWorkGroupParas::getTopAdjustRecv);
    disconnect(&side_cam_focus_sport,&SerialPortHandler::newQByteArrayDataReceived,dialog, &Dialog_configWorkGroupParas::getSideAdjustRecv);

    if(dialog != nullptr)
    {
        delete dialog;
    }
}


void Widget::on_btn_systemConfig_clicked()
{
    Dialog_configSystermParas *dialog = new Dialog_configSystermParas(this);
    dialog->exec();

    if(dialog != nullptr)
    {
        delete dialog;
    }
}


void Widget::do_checkCode(QString code)
{
    qDebug() << "产品码：" << code;

    plc_port.do_plcSendPulse(5, 1100);// 发送启动脉冲信号
}

// 停止设备
void Widget::on_btn_Stop_clicked()
{
    if(false == ui->btn_switch->isEnabled())
    {
        ui->btn_switch->setEnabled(true);
    }
    ui->btn_Stop->setEnabled(false);

    if(ui->btn_switch->text() != QString("复位"))
    {
        emit toResetStatus();   // 重新接收
        return;
    }

    if(do_questionPopup(QString(tr("确定要复位吗？"))))
    {
        emit toResetStatus();   // 复位
    }
}

//光源控制
void Widget::on_btn_LightSourceControl_clicked()
{
#if 0
    // 创建对话框对象的智能指针
    QScopedPointer<Dialog_LightControl> dialog(new Dialog_LightControl(this, Dialog_LightControl::Null));

    // 使用新语法连接信号和槽
    connect(dialog.data(), &Dialog_LightControl::sendTopRoSideLightAdjustData, this, &Widget::sendTopRoSideLightAdjustData);
    connect(dialog.data(), &Dialog_LightControl::sendBottomLightAdjustData, this, &Widget::sendBottomLightAdjustData);
    connect(&top_side_light_sport, &SerialPortHandler::newQStringDataReceived, dialog.data(), &Dialog_LightControl::getRecv);
    connect(&bottom_light_sport, &SerialPortHandler::newQStringDataReceived, dialog.data(), &Dialog_LightControl::getRecv);

    sendTopRoSideLightAdjustData("SA#SB#");

    dialog->exec();
#else
    Dialog_LightControl *dialog = new Dialog_LightControl(this, Dialog_LightControl::Null);


    connect(dialog, &Dialog_LightControl::sendTopRoSideLightAdjustData, this, &Widget::sendTopRoSideLightAdjustData);
    connect(dialog, &Dialog_LightControl::sendBottomLightAdjustData, this, &Widget::sendBottomLightAdjustData);
    connect(&top_side_light_sport, &SerialPortHandler::newQStringDataReceived, dialog, &Dialog_LightControl::getRecv);
    connect(&bottom_light_sport, &SerialPortHandler::newQStringDataReceived, dialog, &Dialog_LightControl::getRecv);

    sendTopRoSideLightAdjustData("SA#SB#");

    dialog->exec();

    disconnect(&top_side_light_sport, &SerialPortHandler::newQStringDataReceived, dialog, &Dialog_LightControl::getRecv);
    disconnect(&bottom_light_sport, &SerialPortHandler::newQStringDataReceived, dialog, &Dialog_LightControl::getRecv);
    disconnect(dialog, &Dialog_LightControl::sendTopRoSideLightAdjustData, this, &Widget::sendTopRoSideLightAdjustData);
    disconnect(dialog, &Dialog_LightControl::sendBottomLightAdjustData, this, &Widget::sendBottomLightAdjustData);

    if(dialog != nullptr)
    {
        delete dialog;
    }
#endif



}

void Widget::sendTopRoSideLightAdjustData(QString dat)
{
//    qDebug()<<dat;
    top_side_light_sport.sendData(dat);
}

void Widget::sendBottomLightAdjustData(QString dat)
{
//    qDebug()<<dat;
    bottom_light_sport.sendData(dat);
}

QByteArray Widget::intToByteArray(int value)
{
    QByteArray byteArray;
    byteArray.resize(4);

    byteArray[0] = (uint8_t)(value >> 24) & 0xFF;
    byteArray[1] = (uint8_t)(value >> 16) & 0xFF;
    byteArray[2] = (uint8_t)(value >> 8) & 0xFF;
    byteArray[3] = (uint8_t) value & 0xFF;

    return byteArray;
}

QByteArray Widget::formSetAngleData(int angle)
{
    QByteArray dat;
    dat.append(0x01);
    dat.append(0x64);
    dat.append(0x01);
    int temp = 100 * 16384 / 6000;
    dat+=intToByteArray(temp);// 速度
    temp = angle * 16384 / 360;
    dat+=intToByteArray(temp);// 角度

    dat.append('\x00');
    dat.append('\x00');
    dat.append('\x00');

    return dat;
}


void Widget::sendSideFormSetData(int angle)
{
    QByteArray dat = formSetAngleData(angle);// 拼接数据帧
    getSideAdjustData(dat);// 发送

    qDebug() << "侧边镜头调焦：" << angle;

//    if(angle < 1480)
//    {
//        qDebug() << "if(angle < 1480) 成立";

//        processor.setInterval(50); // 定时器间隔，单位毫秒
//        processor.addValue(angle); // 示例值
//        processor.startProcessing();
//    } else {
//        qDebug() << "if(angle < 1480) 不成立";
//    }
}

void Widget::sendTopFormSetData(int angle)
{
    QByteArray dat = formSetAngleData(angle);
    getTopAdjustData(dat);

    qDebug() << "顶部镜头调焦：" << angle;

//    if(angle < 1480)
//    {
//        qDebug() << "if(angle < 1480) 成立";

//        processor.setInterval(50); // 定时器间隔，单位毫秒
//        processor.addValue(angle); // 示例值
//        processor.startProcessing();
//    } else {
//        qDebug() << "if(angle < 1480) 不成立";
//    }


}

//镜头调节
void Widget::on_btn_camAdjust_clicked()
{
    ui->btn_camAdjust->setEnabled(false);

    // 校准
    sendTopFormSetData(1480);
    sendSideFormSetData(1480);
    Dialog_camAdjust::topCamadjustValue = 740;
    Dialog_camAdjust::sideCamadjustValue = 740;

    // 延时等待3s
    Delay::waitForTime(3);


    // 设置默认值
    int setAngle = 300;

    int topVal = -(Dialog_camAdjust::topCamadjustValue - setAngle);// 顶部
    int sideVal = -(Dialog_camAdjust::sideCamadjustValue - setAngle);// 侧面

    sendTopFormSetData(topVal);
    sendSideFormSetData(sideVal);
    Dialog_camAdjust::topCamadjustValue = setAngle;
    Dialog_camAdjust::sideCamadjustValue = setAngle;

    // 延时等待1s
    Delay::waitForTime(1);


    Dialog_camAdjust *dialog = new Dialog_camAdjust(this);
    connect(dialog,&Dialog_camAdjust::sendTopAdjustData,this, &Widget::getTopAdjustData);
    connect(dialog,&Dialog_camAdjust::sendSideAdjustData,this, &Widget::getSideAdjustData);
    connect(&top_cam_focus_sport, static_cast<void (SerialPortHandler::*)(const QByteArray)>(&SerialPortHandler::newQByteArrayDataReceived), dialog, &Dialog_camAdjust::getTopRecv);
    connect(&side_cam_focus_sport, static_cast<void (SerialPortHandler::*)(const QByteArray)>(&SerialPortHandler::newQByteArrayDataReceived), dialog, &Dialog_camAdjust::getSideRecv);

    dialog->exec();

    disconnect(dialog,&Dialog_camAdjust::sendTopAdjustData,this, &Widget::getTopAdjustData);
    disconnect(dialog,&Dialog_camAdjust::sendSideAdjustData,this, &Widget::getSideAdjustData);
    disconnect(&top_cam_focus_sport, static_cast<void (SerialPortHandler::*)(const QByteArray)>(&SerialPortHandler::newQByteArrayDataReceived), dialog, &Dialog_camAdjust::getTopRecv);
    disconnect(&side_cam_focus_sport, static_cast<void (SerialPortHandler::*)(const QByteArray)>(&SerialPortHandler::newQByteArrayDataReceived), dialog, &Dialog_camAdjust::getSideRecv);

    if(dialog != nullptr)
    {
        delete dialog;
    }

    ui->btn_camAdjust->setEnabled(true);
}

void Widget::getTopAdjustData(QByteArray dat)
{
    QString str_dat = "Top 发送给镜头(HEX)：";

    uint16_t wcrc = ModbusCRC16(dat);
//    qDebug()<<"CRC码：低字节:"<< QString("%1").arg(uint8_t(wcrc), 2, 16, QChar('0')).toUpper()
//            <<" 高字节:"<< QString("%1").arg(uint8_t(wcrc>>8), 2, 16, QChar('0')).toUpper();

    dat.append(uint8_t(wcrc));
    dat.append(uint8_t(wcrc>>8));

    qDebug() << str_dat << dat.toHex().toUpper();

    top_cam_focus_sport.sendData(dat);
}

void Widget::getSideAdjustData(QByteArray dat)
{

    QString str_dat = "Side 发送给镜头(HEX)：";

    uint16_t wcrc = ModbusCRC16(dat);
//    qDebug()<<"CRC码：低字节:"<< QString("%1").arg(uint8_t(wcrc), 2, 16, QChar('0')).toUpper()
//            <<" 高字节:"<< QString("%1").arg(uint8_t(wcrc>>8), 2, 16, QChar('0')).toUpper();

    dat.append(uint8_t(wcrc));
    dat.append(uint8_t(wcrc>>8));

    qDebug() << str_dat << dat.toHex().toUpper();

    side_cam_focus_sport.sendData(dat);
}


void Widget::do_updatelatestStatusCode(const uint16_t statusCode)
{
    qDebug() << "接收到新状态 ：" << statusCode;

    plcStateBit = statusCode;

    if(statusCode >= currentSteps.size())
    {
        ui->LineEdit_currentStep->setText("暂时没有该状态位");
        return;
    }

//    static bool startFlag = false;

//    if(false == startFlag)
//    {
//        if(plcStateBit >= 2) {
//            startFlag = true;
//        }
//    } else {
//        if(plcStateBit < 2) {
//            if( MessageBoxUtil::Yes == MessageBoxUtil::showMessage(this, MessageBoxUtil::Critical, "错误", "检测到plc复位，是否同步"))
//            {
//                startFlag = false;


//                setTextColor(ui->label_devCurrState, "检测到PLC复位...", StatusColor::Other);
//    //            // 复位
//    //            plc_port.do_setSendModbusRequest(5, 1102, 0xFF00);
//    //            plc_port.do_setSendModbusRequest(5, 1102, 0x00);

//                // 定时器等待10秒
//                waitForTime(10);

//            //    emit toNextState();

//                m_productUniqueCode.clear();
//                m_getHttpCsvFlag = true;
//                m_productCodeFlag = false;

//                emit resetForScanState();// 复位
//            }
//        }
//    }


    // 更新到显示框
    ui->LineEdit_latestStatusCode->setText(QString::number(statusCode));
    ui->LineEdit_currentStep->setText(currentSteps.at(statusCode));
}

void Widget::do_initSerialPort()
{
    bool FlagLight = top_side_light_sport.openPort(2,"topCameraLightNuberOf1");
    if(!FlagLight)
    {
        top_side_light_sport.setConnectStatus(false);

        setTextColor(ui->LineEdit_lightConnStateA, "未连接", StatusColor::Error);
        setTextColor(ui->LineEdit_lightConnStateA_2, "未连接", StatusColor::Error);
    } else {
        top_side_light_sport.setConnectStatus(true);

        setTextColor(ui->LineEdit_lightConnStateA, "已连接", StatusColor::Success);
        setTextColor(ui->LineEdit_lightConnStateA_2, "已连接", StatusColor::Success);
    }

    bool topFlagFocusRing = top_cam_focus_sport.openPort(1,"topCameraFocusRingNuberOf1");
    if(!topFlagFocusRing)
    {
        top_cam_focus_sport.setConnectStatus(false);
        setTextColor(ui->LineEdit_cameraConnStateA, "未连接", StatusColor::Error);
    } else {
        top_cam_focus_sport.setConnectStatus(true);
        setTextColor(ui->LineEdit_cameraConnStateA, "已连接", StatusColor::Success);
    }

    bool bottomFlagLight = bottom_light_sport.openPort(2,"bottomCameraLightNuberOf2");
    if(!bottomFlagLight)
    {
        bottom_light_sport.setConnectStatus(false);
        setTextColor(ui->LineEdit_otherInfo_2, "未连接", StatusColor::Error);
        setTextColor(ui->lineEdit_sideFillLightState, "未连接", StatusColor::Error);
    } else {
        bottom_light_sport.setConnectStatus(true);
        setTextColor(ui->LineEdit_otherInfo_2, "已连接", StatusColor::Normal);
        setTextColor(ui->lineEdit_sideFillLightState, "已连接", StatusColor::Success);
    }

    bool sideFlagFocusRing = side_cam_focus_sport.openPort(1,"LineEdit_sideCameraFocusRingNuberOf1");
    if(!sideFlagFocusRing)
    {
        bottom_light_sport.setConnectStatus(false);
        setTextColor(ui->LineEdit_cameraConnStateB, "未连接", StatusColor::Error);
    } else {
        bottom_light_sport.setConnectStatus(true);
        setTextColor(ui->LineEdit_cameraConnStateB, "已连接", StatusColor::Success);
    }

    if(plc_port.startPort())
    {
      plc_port.setPlcConnectState(true);
      setTextColor(ui->LineEdit_PlcState, "已连接", StatusColor::Error);
      plc_state_flag = true;
    } else {
        plc_port.setPlcConnectState(false);
        setTextColor(ui->LineEdit_PlcState, "未连接", StatusColor::Success);
    }

    if(FlagLight && topFlagFocusRing && bottomFlagLight && sideFlagFocusRing && plc_state_flag)
    {
        m_portGlobalFlag = true;
    } else {
        m_portGlobalFlag = false;
    }

    m_checkPortFlag = true;
    m_checkPortTime = 3;// 设置检测时间，每3秒钟检测一次

}

void Widget::do_closeSerialPort()
{
    top_side_light_sport.closePort();
    top_cam_focus_sport.closePort();
    bottom_light_sport.closePort();
    side_cam_focus_sport.closePort();


    setTextColor(ui->LineEdit_lightConnStateA, "已断开", StatusColor::Error);
    setTextColor(ui->LineEdit_lightConnStateA_2, "已断开", StatusColor::Error);
    setTextColor(ui->LineEdit_cameraConnStateA, "已断开", StatusColor::Error);

    setTextColor(ui->lineEdit_sideFillLightState, "已断开", StatusColor::Error);

    setTextColor(ui->LineEdit_otherInfo_2, "已断开", StatusColor::Error);
    setTextColor(ui->LineEdit_cameraConnStateB, "已断开", StatusColor::Error);

    if(true == plc_state_flag)
    {
        plc_port.closePort();
        setTextColor(ui->LineEdit_PlcState, "已断开", StatusColor::Error);
        plc_state_flag =  false;
    }
}


void Widget::on_btn_switch_clicked()
{
    // 检查设备端口连接状态
    if(false == device_switch_flag)
    {
        setTextColor(ui->label_devCurrState, "设备端口连接异常", StatusColor::Error);
        return;
    }

    // 开启状态机
    ui->btn_switch->setEnabled(false);
    ui->btn_Stop->setEnabled(true);
    m_nextStateFlag = true;// 状态机跳转开启
}

//CRC16计算函数
uint16_t Widget::ModbusCRC16(QByteArray senddata)
{
    int len=senddata.size();
    uint16_t wcrc=0XFFFF;//预置16位crc寄存器，初值全部为1
    uint8_t temp;//定义中间变量
    int i=0,j=0;//定义计数
    for(i=0;i<len;i++)//循环计算每个数据
    {
       temp=senddata.at(i);
       wcrc^=temp;
       for(j=0;j<8;j++){
          //判断右移出的是不是1，如果是1则与多项式进行异或。
          if(wcrc&0X0001){
              wcrc>>=1;//先将数据右移一位
              wcrc^=0XA001;//与上面的多项式进行异或
          }
          else//如果不是1，则直接移出
              wcrc>>=1;//直接移出
       }
    }
    temp=wcrc;//crc的值
    return wcrc;
}


void Widget::do_setCurrentGroupData(const QMap<QString, QString> map_group)
{
    map_currentGroup = map_group;

    setTextColor(ui->LineEdit_currentWorkGroup, map_currentGroup.value("currentGroup"), StatusColor::Normal);
    setTextColor(ui->LineEdit_workGroupSize, map_currentGroup.value("size"), StatusColor::Normal);

    emit sendCurrentWorkGroupData(map_currentGroup);

    qDebug() << "收到了 Map_Group:" << map_group;
}



/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* MyStateMachine Code */
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

void Widget::MyStateMachineInit()
{
//    InitMachine();
    m_stateMachine = new myStateMachine(this);

    m_stateMachine->InitMachine();

    // 绑定信号槽

    // 跳转状态机
    connect(this, &Widget::toStateWork, m_stateMachine, &myStateMachine::toStateWork);
    connect(this, &Widget::toNextState, m_stateMachine, &myStateMachine::toNextState);
    connect(this, &Widget::toResetStatus, m_stateMachine, &myStateMachine::toResetStatus);

    // PLC
    connect(m_stateMachine, &myStateMachine::sendPulse, &plc_port, &ModbusSerialTest::do_plcSendPulse);
    connect(m_stateMachine, &myStateMachine::sendModbusRequest, &plc_port, &ModbusSerialTest::do_setSendModbusRequest);

    // 光源
    connect(m_stateMachine, &myStateMachine::sendTopLigth, this, &Widget::do_setTopLight);
    connect(m_stateMachine, &myStateMachine::sendSideLigth, this, &Widget::do_setSideLight);
    connect(m_stateMachine, &myStateMachine::sendFillLigth, this, &Widget::do_setFillLight);
    connect(m_stateMachine, &myStateMachine::sendBottomLigth, this, &Widget::do_setBottomLight);
    connect(m_stateMachine, &myStateMachine::sendAllLigth, this, &Widget::do_setAllLight);

    // 镜头
    connect(m_stateMachine, &myStateMachine::sendTopFormSetData, this, &Widget::sendTopFormSetData);
    connect(m_stateMachine, &myStateMachine::sendSideFormSetData, this, &Widget::sendSideFormSetData);

    connect(m_stateMachine, &myStateMachine::sendTopFormSetData, this, &Widget::do_initTopFocus);
    connect(m_stateMachine, &myStateMachine::sendSideFormSetData, this, &Widget::do_initSideFocus);

    connect(m_stateMachine, &myStateMachine::setTopCamFocusLight, this, &Widget::setTopCamFocusLight);
    connect(m_stateMachine, &myStateMachine::setSideCamFocusLight, this, &Widget::setSideCamFocusLight);

    // 拍照
    connect(m_stateMachine, &myStateMachine::sendTopPhoto, this, &Widget::do_TopPhoto);
    connect(m_stateMachine, &myStateMachine::sendAFacePhoto, this, &Widget::do_AFacePhoto);
    connect(m_stateMachine, &myStateMachine::sendBFacePhoto, this, &Widget::do_BFacePhoto);
    connect(m_stateMachine, &myStateMachine::sendCFacePhoto, this, &Widget::do_CFacePhoto);
    connect(m_stateMachine, &myStateMachine::sendDFacePhoto, this, &Widget::do_DFacePhoto);
    connect(m_stateMachine, &myStateMachine::sendBottomPhoto, this, &Widget::do_BottomPhoto);

    // 新增工作组
    connect(m_stateMachine, &myStateMachine::sendNewWorkGroup, this, &Widget::do_showAddWorkGroup);

    // 切换工作组
    connect(m_stateMachine, &myStateMachine::sendUpdatePlcGroup, this, &Widget::do_updatePlcGroupData);

    // 点击【停止获取】
    connect(m_stateMachine, &myStateMachine::sendClickBtnStop, this, &Widget::on_btn_Stop_clicked);

    // 更新当前选中组
    connect(m_stateMachine, &myStateMachine::sendUpdateCurrentGroup, this, &Widget::do_updateCurrentGroup);

    // 初始化镜头焦距
    connect(m_stateMachine, &myStateMachine::sendInitFocus, this, &Widget::do_initFocus);

    // 弹出信息提示窗口
    connect(m_stateMachine, &myStateMachine::sendQuestionPopup, this, &Widget::do_questionPopup);

    // 初始化定时器
    StateMachineTimer = new QTimer(this);
    // 连接定时器的timeout()信号到自定义槽函数
    connect(StateMachineTimer, &QTimer::timeout, this, &Widget::onTimeoutStateMachine);
    // 设置定时器间隔为1000毫秒（即1秒）
    StateMachineTimer->start(1000);

    // 启动状态机
//    machine->start();
}

void Widget::onTimeoutStateMachine()
{
    static uint16_t time_count = 0;

    time_count++;

    // 周期性检查端口连接状态
    if(true == m_checkPortFlag)
    {
//        do_initSerialPort();

        uint16_t checkPortCount = time_count %= m_checkPortTime;

        if(0 == checkPortCount)
        {
            qDebug() << "检查各个端口连接状态...";

            // 更新端口连接状态
            updatePortConnectStatus();
        }
    }


    if(false == ui->btn_switch->isEnabled())
    {
        qDebug() << "--正在进行当前状态的任务---->";
        emit toStateWork();
    }

}


void Widget::updatePortConnectStatus()
{

//    bool httpFlag = m_http->isUrlValid(HttpRequest::m_requestHeader);
    bool httpFlag = true;

//    m_http->isUrlValid(HttpRequest::m_requestHeader);
//    m_http->isUrlValid("www.baidu.com");

    // PLC端口，连接状态更新
    bool plcFlag = plc_port.checkConnectState();
    if(plcFlag)
    {
        setTextColor(ui->LineEdit_PlcState, "已连接", StatusColor::Success);
    } else {
        setTextColor(ui->LineEdit_PlcState, "已断开", StatusColor::Error);
    }

    // 工位1顶部光源端口，连接状态更新
    bool topLightFlag = top_side_light_sport.checkConnectState();
    if(topLightFlag)
    {
        setTextColor(ui->LineEdit_lightConnStateA, "已连接", StatusColor::Success);
        setTextColor(ui->LineEdit_lightConnStateA_2, "已连接", StatusColor::Success);
    } else {
        setTextColor(ui->LineEdit_lightConnStateA, "已断开", StatusColor::Error);
        setTextColor(ui->LineEdit_lightConnStateA_2, "已断开", StatusColor::Error);
    }

    // 工位1顶部镜头调焦端口,连接状态更新
    bool topFocusFlag = top_cam_focus_sport.checkConnectState();
    if(topFocusFlag)
    {
        setTextColor(ui->LineEdit_cameraConnStateA, "已连接", StatusColor::Success);
    } else {
        setTextColor(ui->LineEdit_cameraConnStateA, "已断开", StatusColor::Error);
    }

    // 工位2底部光源端口,连接状态更新
    bool bottomLightFlag = bottom_light_sport.checkConnectState();
    if(bottomLightFlag)
    {
        setTextColor(ui->LineEdit_otherInfo_2, "已连接", StatusColor::Success);
        setTextColor(ui->lineEdit_sideFillLightState, "已连接", StatusColor::Success);
    } else {
        setTextColor(ui->LineEdit_otherInfo_2, "已断开", StatusColor::Error);
        setTextColor(ui->lineEdit_sideFillLightState, "已断开", StatusColor::Error);
    }

    // 工位2底部光源端口,连接状态更新
    bool sideFocusFlag = side_cam_focus_sport.checkConnectState();
    if(sideFocusFlag)
    {
        setTextColor(ui->LineEdit_cameraConnStateB, "已连接", StatusColor::Success);
    } else {
        setTextColor(ui->LineEdit_cameraConnStateB, "已断开", StatusColor::Error);
    }


    if(true == httpFlag && true == plcFlag && true == topFocusFlag && true == sideFocusFlag && true == topLightFlag && true == bottomLightFlag)
    {
        device_switch_flag = true;
    } else {
        device_switch_flag = false;
    }
}

// 顶部光源
void Widget::do_setTopLight(uint8_t value)
{
    QString sDataString = getDataString(value);
    sendTopRoSideLightAdjustData(QString("SA%1#SB%2#").arg(sDataString).arg(sDataString));
}
// 侧面光源
void Widget::do_setSideLight(uint8_t value)
{
    QString sDataString = getDataString(value);
    sendTopRoSideLightAdjustData(QString("SC%1#SD%2#").arg(sDataString).arg(sDataString));
}
// 侧面补光
void Widget::do_setFillLight(uint8_t value)
{
    QString sDataString = getDataString(value);
    sendBottomLightAdjustData(QString("SB%1#").arg(sDataString));
}
// 底部光源
void Widget::do_setBottomLight(uint8_t value)
{
    QString sDataString = getDataString(value);
    sendBottomLightAdjustData(QString("SA%1#").arg(sDataString));
}
// 所有光源
void Widget::do_setAllLight(uint8_t value)
{
    QString sDataString = getDataString(value);

    sendBottomLightAdjustData(QString("SA%1#SB%2#").arg(sDataString).arg(sDataString));
    sendTopRoSideLightAdjustData(QString("SA%1#SB%2#SC%3#SD%4#").arg(sDataString).arg(sDataString).arg(sDataString).arg(sDataString));
}

// 初始化焦距
void Widget::do_initFocus()
{
    // 校准
    sendTopFormSetData(1480);
    sendSideFormSetData(1480);
    Dialog_camAdjust::topCamadjustValue = 740;
    Dialog_camAdjust::sideCamadjustValue = 740;

#if 0
    // 延时等待2s
    Delay::waitForTime(2);

    // 设置默认值
    int setAngle = 300;

    int topVal = -(Dialog_camAdjust::topCamadjustValue - setAngle);// 顶部
    int sideVal = -(Dialog_camAdjust::sideCamadjustValue - setAngle);// 侧面

    sendTopFormSetData(topVal);
    sendSideFormSetData(sideVal);
    Dialog_camAdjust::topCamadjustValue = setAngle;
    Dialog_camAdjust::sideCamadjustValue = setAngle;

    // 延时等待2s
    Delay::waitForTime(2);
#endif
}


void Widget::do_showAddWorkGroup(QString productClass)
{
//    // 没有找到，请添加工作组配置
//    if(QMessageBox::Yes == MessageBoxUtil::showMessage(this, MessageBoxUtil::Warning, "提示", QString("没有找到 %1 绑定的工作组，请添加工作组配置!").arg(productClass)))
//    {
//        do_btn_configWorkGroup_clicked(productClass);
//    }

//    ui->label_statusBer->show();
//    setTextColor(ui->label_statusBer, QString("没有找到 %1 绑定的工作组，请添加工作组配置!").arg(productClass), StatusColor::Error);
}

void Widget::do_updateCurrentGroup(QString groupId)
{
    QString size = m_iniManager->readValue(groupId, "size").toString();
    QString name = m_iniManager->readValue(groupId, "name").toString();

    m_iniManager->writeValue("current", "group", groupId);
    GetCurrentGroupData();
}

void Widget::do_updatePlcGroupData(QString productUniqueCode)
{
#if 1
    QString GroupId = m_iniManager->readValue("current", "group").toString();

    QString name = m_iniManager->readValue(GroupId, "name").toString();
    QString size = m_iniManager->readValue(GroupId, "size").toString();
    QString productClass = m_iniManager->readValue(GroupId, "productClass").toString();

    GetCurrentGroupData();
    qDebug() << "切换工作组！";
    updatePlcGroupData(GroupId);

//    // 定时器等待10秒
//    Delay::waitForTime(10);
#else
    QString GroupId = m_iniManager->readValue("current", "group").toString();

    QString name = m_iniManager->readValue(GroupId, "name").toString();
    QString size = m_iniManager->readValue(GroupId, "size").toString();
    QString productClass = m_iniManager->readValue(GroupId, "productClass").toString();

    Dialog_InputCode *dialog = new Dialog_InputCode(this, productUniqueCode, name, size, productClass);
    connect(this, &Widget::plcChainWidthCurrentSize, dialog, &Dialog_InputCode::do_setCurrentGroupSize);
    if(dialog->exec() == QDialog::Accepted)
    {
        GetCurrentGroupData();
        qDebug() << "切换工作组！";
        updatePlcGroupData(map_currentGroup.value("currentGroup"));

        // 定时器等待10秒
        Delay::waitForTime(10);

        // PLC 复位完成后的操作
        do_checkCode(productUniqueCode);
        m_productCodeFlag = true;
        emit toNextState();
    } else {
        productUniqueCode.clear();
        m_getHttpCsvFlag = true;
        m_productCodeFlag = false;
        // emit resetIdleState();
        emit resetForScanState();// 跳转到等待扫描
    }
    disconnect(this, &Widget::plcChainWidthCurrentSize, dialog, &Dialog_InputCode::do_setCurrentGroupSize);

    if(dialog != nullptr)
        delete dialog;
#endif
}


// 清理所有标志位
void Widget::clearAllFlag()
{
    m_productUniqueCode.clear();
    m_getHttpCsvFlag = true;
    m_productCodeFlag = false;
}



// 生成并返回格式化的数据字符串 (0000)
QString Widget::getDataString(uint8_t light)
{
    QString sData="0";

    uint8_t val = light;
    if(val < 10) sData += "0";
    if(val < 100) sData += "0";
    sData += QString("%1").arg(val);

    return sData;
}

void Widget::setLightAll(uint8_t light)
{
//    QString sData = Dialog_LightControl::getSetLightsDataString("A", light);

    QString sDataString = getDataString(light);

    sendBottomLightAdjustData(QString("SA%1#SB%2#").arg(sDataString).arg(sDataString));
    sendTopRoSideLightAdjustData(QString("SA%1#SB%2#SC%3#SD%4#").arg(sDataString).arg(sDataString).arg(sDataString).arg(sDataString));
}

//// 封装定时器的函数
//template<typename Callable>
//void Widget::setTimeout(Callable&& func, int interval) {
//    // 创建一个定时器对象
//    QTimer* timer = new QTimer();

//    // 使用智能指针管理传入的可调用对象
//    auto task = std::make_shared<std::decay_t<Callable>>(std::forward<Callable>(func));

//    QObject::connect(timer, &QTimer::timeout, [timer, task]() {
//        (*task)(); // 调用传入的函数
//        timer->stop(); // 停止定时器
//        timer->deleteLater(); // 延迟删除定时器对象
//    });

//    timer->setSingleShot(true); // 设置定时器为单次触发
//    timer->start(interval); // 启动定时器
//}


void Widget::do_TopPhoto()
{
    setTextColor(ui->label_devCurrState, "顶部拍照...", StatusColor::Normal);
    // 顶部镜头、光源调整为顶部参数
    int targetFocus = map_currentGroup.value("topCamFocusVal").toInt();
    uint8_t topLight = map_currentGroup.value("topLightVale").toUInt();
    setTopCamFocusLight(targetFocus, topLight);

    qDebug() << "进入了 do_TopPhoto 槽函数.";

//    // 延时3秒
//    Delay::waitForTime(PHOTO_TIME_DELAY);
}

void Widget::do_AFacePhoto()
{
    setTextColor(ui->label_devCurrState, "A面拍照...", StatusColor::Normal);
    // 侧面镜头、光源调整为配方A面参数
    int targetFocus = map_currentGroup.value("sideCamFocusVal_A").toInt();
    uint8_t sideLight = map_currentGroup.value("sideCamLightVal_A").toUInt();
    uint8_t FillLight = map_currentGroup.value("sideFillLightVal_A").toUInt();
    setSideCamFocusLight(targetFocus, sideLight, FillLight);

//    // 延时3秒
//    Delay::waitForTime(PHOTO_TIME_DELAY);
}

void Widget::do_BFacePhoto()
{
    setTextColor(ui->label_devCurrState, "B面拍照...", StatusColor::Normal);
    // 侧面镜头、光源调整为配方B面参数
    int targetFocus = map_currentGroup.value("sideCamFocusVal_B").toInt();
    uint8_t sideLight = map_currentGroup.value("sideCamLightVal_B").toUInt();
    uint8_t FillLight = map_currentGroup.value("sideFillLightVal_B").toUInt();
    setSideCamFocusLight(targetFocus, sideLight, FillLight);

//    // 延时3秒
//    Delay::waitForTime(PHOTO_TIME_DELAY);
}

void Widget::do_CFacePhoto()
{
    setTextColor(ui->label_devCurrState, "C面拍照...", StatusColor::Normal);
    // 侧面镜头、光源调整为配方C面参数
    int targetFocus = map_currentGroup.value("sideCamFocusVal_C").toInt();
    uint8_t sideLight = map_currentGroup.value("sideCamLightVal_C").toUInt();
    uint8_t FillLight = map_currentGroup.value("sideFillLightVal_C").toUInt();
    setSideCamFocusLight(targetFocus, sideLight, FillLight);

//    // 延时3秒
//    Delay::waitForTime(PHOTO_TIME_DELAY);
}

void Widget::do_DFacePhoto()
{
    setTextColor(ui->label_devCurrState, "D面拍照...", StatusColor::Normal);

    // 侧面镜头、光源调整为配方D面参数
    int targetFocus = map_currentGroup.value("sideCamFocusVal_D").toInt();
    uint8_t sideLight = map_currentGroup.value("sideCamLightVal_D").toUInt();
    uint8_t FillLight = map_currentGroup.value("sideFillLightVal_D").toUInt();
    setSideCamFocusLight(targetFocus, sideLight, FillLight);

//    // 延时3秒
//    Delay::waitForTime(PHOTO_TIME_DELAY);
}

void Widget::do_BottomPhoto()
{
    setTextColor(ui->label_devCurrState, "底部拍照...", StatusColor::Normal);
    uint8_t bottomLight = map_currentGroup.value("bottomLightVal").toUInt();
    setBottomCamLight(bottomLight);// 关灯

//    // 延时3秒
//    Delay::waitForTime(PHOTO_TIME_DELAY);
}

QMap<QString, QVariant> Widget::parseCsvToMap(const QString &csvString) {
    QMap<QString, QVariant> resultMap;

    // 按行分割 CSV 字符串
    QStringList lines = csvString.split("\n", QString::SkipEmptyParts);

    if (lines.size() < 2) {
        qWarning() << "CSV string does not contain enough lines.";
        return resultMap;
    }

    // 获取标题行和数据行
    QStringList headers = lines[0].split(",");
    QStringList values = lines[1].split(",");

    // 将标题和对应的值存入 QMap
    for (int i = 0; i < headers.size() && i < values.size(); ++i) {
        resultMap.insert(headers[i], values[i]);
    }

    return resultMap;
}


QString Widget::ensureThreeDigits(const QString &input) {
    QString strTemp = input;

    // 使用正则表达式匹配数字
    QRegExp numberRx("\\d+");
    if (numberRx.indexIn(strTemp) != -1) {
        QString numberStr = numberRx.cap(0); // 提取匹配到的数字
        int number = numberStr.toInt(); // 将字符串转换为整数
        // 使用QString的arg函数来格式化数字，确保至少三位，不足则补零
        return QString("%1").arg(number, 3, 10, QChar('0'));
    }
    // 如果输入字符串中没有数字，返回原始字符串或空字符串，根据你的需求
    if(strTemp.size() < 3) {
        strTemp.prepend('0');
    }
    return strTemp; // 或者 return QString();
}


// 获取颜色函数
QColor Widget::getColor(StatusColor status) {
    return QColor(static_cast<QRgb>(status));
}

// 模板函数来设置控件的文本和颜色
template<typename T>
void Widget::setTextColor(T *widget, const QString &text, StatusColor status) {
    // 空指针检查
    if (widget == nullptr) {
        qDebug() << "控件指针为NULL，空指针访问!";
        return;
    }

    try {
        // 设置文本
        widget->setText(text);

        // 设置颜色
        QPalette palette = widget->palette();

        if (std::is_same<T, QLineEdit>::value) {
            palette.setColor(QPalette::Text, getColor(status));
        } else if (std::is_same<T, QLabel>::value) {
            palette.setColor(QPalette::WindowText, getColor(status));
        } else {
            qDebug() << "不支持的控件类型!";
            return;
        }
        widget->setPalette(palette);
    } catch (const std::exception &e) {
        qDebug() << "设置文本或颜色时发生异常:" << e.what();
    } catch (...) {
        qDebug() << "设置文本或颜色时发生未知异常";
    }
}

bool Widget::do_questionPopup(const QString &text)
{
    bool flag = (QMessageBox::Yes == MessageBoxUtil::showMessage(this, MessageBoxUtil::Warning, "提示", text));

    return flag;
}


void Widget::deleteStateMachine()
{
#if 0
    // 首先，停止状态机（如果它在运行）
    if (machine && machine->isRunning()) {
        machine->stop();
    }

    // 删除状态机及其所有状态
    delete finalSelfTest;
    delete plcSelfTest;
    delete industrialCtrlNetSelfTest;
    delete secretMachineSelfTest;
    delete cameraConnSelfTest;
    delete lightSelfTest;
    delete cameraSelfTest;
    delete stoppedState;
    delete resetStartedState;
    delete cameraState;
    delete forScanState;
    // delete stateInit;
    delete idleState;
    delete waitingForScanState;
    delete writBbufferState;
    delete workpieceArrives1;
    delete ForScanFinal;
    delete photoTop;
    delete photoFaceA;
    delete photoFaceB;
    delete photoFaceC;
    delete photoFaceD;
    delete photoBottom;
    delete cameraFinal;
    delete cuttingSensorStatus;
    delete SingleJobResetComplete;
    delete resetStatus;
    delete resetFinal;

    // 最后，删除状态机本身
    delete machine;

    // 将所有指针设置为nullptr，以防止悬空指针
    machine = nullptr;
    idleState = nullptr;
    // ... （对所有其他指针也做同样的操作）
#endif
}

